package com.ebraga.trackerclub.android.dao.core;

import java.util.ArrayList;
import java.util.List;

import android.database.Cursor;

import com.ebraga.trackerclub.android.dao.api.UserDao;
import com.ebraga.trackerclub.android.dao.entity.UserAndroid;
import com.ebraga.trackerclub.android.exception.BackofficeDBConnectionException;
import com.ebraga.trackerclub.android.exception.dao.BackofficeDaoException;
import com.ebraga.trackerclub.android.exception.dao.BackofficeIllegalArgumentDaoException;
import com.ebraga.trackerclub.android.util.ISmartServiceConstants;
import com.ebraga.trackerclub.android.util.api.AndroidContentValues;
import com.ebraga.trackerclub.android.util.api.AndroidSQLiteDatabase;
import com.ebraga.trackerclub.android.util.api.DataAccessObject;

public abstract class UserDaoImpl implements UserDao {

	private DataAccessObject dataAccessObject = null;
	private AndroidContentValues contentValues;
	Cursor c;
	String tableName = "user";
	String[] select = new String[] {NAME, BRAND, MODEL, IMEI, LAST_LOGIN};
	
	// Column names
	public static final String BRAND 						= "brand";
	public static final String NAME 						= "name";
	public static final String IMEI 						= "imei";
	public static final String MODEL						= "model";
	public static final String LAST_LOGIN					= "lastLogin";

	protected UserDaoImpl(DataAccessObject dataAccessObject) {
		this.dataAccessObject = dataAccessObject;
		
	}	
	
	protected void setContentValues(AndroidContentValues contentValues) {
		this.contentValues = contentValues;
	}
	
	public UserAndroid loginOffLine(String username) throws BackofficeDBConnectionException, BackofficeDaoException {
		
		try{
			
			UserAndroid userAndroid = null;
			String where = IMEI + " = ? ";
			String[] whereArgs = new String[] {username}; 
			String orderBy = LAST_LOGIN;			
			
			AndroidSQLiteDatabase sQLiteDatabase = dataAccessObject.getDB();
			Cursor c = sQLiteDatabase.query(tableName, select, where, whereArgs, null, null, orderBy); 
			
			List<UserAndroid> result = getRecordsFromCursor(c);
			
			if (result != null && result.size() > 0) {
				userAndroid =  result.get(0);
			}
			
			c.close();
			
			return userAndroid;
			
		} catch (RuntimeException e) {
			throw new BackofficeDBConnectionException(e.getMessage());
		} catch (Exception e) {
			throw new BackofficeDaoException(e);
		}
				
	}
	
	public Long insert(UserAndroid user) throws BackofficeDBConnectionException, BackofficeDaoException {
		
		long returnInsertUpdate  = 0;
		
		if (validateEntityToPersist(user)) {
		
			contentValues.put(NAME, user.getName());
			contentValues.put(IMEI, user.getImei());
			contentValues.put(BRAND, user.getBrand());
			contentValues.put(MODEL, user.getModel());
			contentValues.put(LAST_LOGIN, user.getLastLogin());
	
			returnInsertUpdate = dataAccessObject.getDB().insert(tableName, contentValues);
			
		}
		
		return returnInsertUpdate;			
	}

	public Long update(UserAndroid user) throws BackofficeDBConnectionException, BackofficeDaoException {
		
		long returnInsertUpdate  = 0;
		
		if (validateEntityToPersist(user)) {
		
			String where = IMEI + " = ? ";
			String[] whereArgs = new String[] {user.getImei()}; 
			
			
			contentValues.put(IMEI, user.getImei());
			contentValues.put(NAME, user.getName());
			contentValues.put(BRAND, user.getBrand());
			contentValues.put(MODEL, user.getModel());
			contentValues.put(LAST_LOGIN, user.getLastLogin());
	
			returnInsertUpdate = dataAccessObject.getDB().update(tableName, contentValues, where, whereArgs);
		
		}
		
		return returnInsertUpdate;	
		
	}

	private boolean validateEntityToPersist(UserAndroid user) throws BackofficeIllegalArgumentDaoException {
		
		if (user.getImei() == null || user.getName() == null || user.getBrand() == null) {
			throw new BackofficeIllegalArgumentDaoException(ISmartServiceConstants.ERROR_CODE.INVALID_LOGIN_OFF_LINE);
		}
		
		return true;

	}	
	
	public UserAndroid lastLogin() throws BackofficeDBConnectionException, BackofficeDaoException {

		try{
			
			UserAndroid userAndroid = null;
			String orderBy = LAST_LOGIN;			
			
			AndroidSQLiteDatabase sQLiteDatabase = dataAccessObject.getDB();
			Cursor c = sQLiteDatabase.query(tableName, select, null, null, null, null, orderBy); 
			
			List<UserAndroid> result = getRecordsFromCursor(c);
			
			if (result != null && result.size() > 0) {
				userAndroid =  result.get(0);
			}
			
			c.close();
			
			return userAndroid;
			
		} catch (RuntimeException e) {
			throw new BackofficeDBConnectionException();
		} catch (Exception e) {
			throw new BackofficeDaoException(e);
		}
	}
	
	public UserAndroid getUser(String login)
			throws BackofficeIllegalArgumentDaoException,
			BackofficeDBConnectionException, BackofficeDaoException {
		UserAndroid user = new UserAndroid();
		
		if (login == null){
			throw new BackofficeIllegalArgumentDaoException("Usuario invalido");
		}
		
		String where = IMEI + " = ? ";
		String[] whereArgs = new String[] {login};
		AndroidSQLiteDatabase sQLiteDatabase;
		String orderBy = LAST_LOGIN + " DESC";
		
		try{
			sQLiteDatabase = dataAccessObject.getDB();
		}catch (BackofficeDaoException de){
			throw new BackofficeDBConnectionException("Erro ao conectar banco de dados");
		}
		
		try{
			c = sQLiteDatabase.query(tableName, select, where, whereArgs, null, null, orderBy);
		}catch(Exception e){
			throw new BackofficeDaoException("Erro ao executar query");
		}
		
		List<UserAndroid> result = getRecordsFromCursor(c);
		
		if (result != null && result.size() > 0) {
			user =  result.get(0);
		}
		
		c.close();
		
		return user;
	}
	
	

	/**
	 * Get full INC record from DB
	 * 
	 * @param c
	 */
	public List<UserAndroid> getRecordsFromCursor(Cursor cursor) {
		
		List<UserAndroid> result = new ArrayList<UserAndroid>();
		
		while (cursor.moveToNext()) {
			
			UserAndroid userAndroid = new UserAndroid();
			userAndroid.setImei(cursor.getString(cursor.getColumnIndexOrThrow(IMEI)));
			userAndroid.setLastLogin(cursor.getLong(cursor.getColumnIndexOrThrow(LAST_LOGIN)));
			userAndroid.setName(cursor.getString(cursor.getColumnIndexOrThrow(NAME)));
			userAndroid.setModel(cursor.getString(cursor.getColumnIndexOrThrow(MODEL)));
			userAndroid.setBrand(cursor.getString(cursor.getColumnIndexOrThrow(BRAND)));

			result.add(userAndroid);
		}

		return result;
	}	

	
}
